package dominio.redeneural;

import java.util.List;

import dominio.ativacao.FuncaoAtivacao;
import dominio.camadaneural.CamadaNeural;
import dominio.neuronio.Neuronio;
import dominio.padrao.Padrao;

/**
 * @author Paulo Vitor
 * @author Roberto Su
 * 
 * @description
 *
 */
public interface RedeNeural {
	
	/**
	 * Método que adiciona uma camada a rede neural. 
	 * 
	 * @param camadaNeural
	 */
	void adicionarCamadaNeural(CamadaNeural camadaNeural);
	
	/**
	 * Método que remove uma camada a rede neural
	 * 
	 * @param camadaNeural
	 * @return
	 */
	boolean removerCamadaNeural(CamadaNeural camadaNeural);
	
	/**
	 * Método que recebe estimulos e os propaga para a camada inicial
	 * da rede neural.
	 * 
	 * @param estimulos
	 * @return
	 */
	double[] estimularRedeNeural(Padrao padrao);
	
	/**
	 * Método que gera as camadas de uma rede neural a partir dos parâmetros de entrada.
	 * 
	 * @param quantidadeCamadas
	 * @param quantidadeNeuronios
	 * @param tiposNeuronios
	 * @throws IllegalArgumentException
	 */
	void criarCamadasNeurais(int quantidadeCamadas, int[] quantidadeNeuronios, Class<? extends Neuronio> tipoNeuronio, FuncaoAtivacao[] funcoesAtivacao) throws IllegalArgumentException;
	
	/**
	 * Método que cria uma camada neural de acordo com os parâmetros de entrada.
	 * 
	 * @param quantidadeNeuronios
	 * @param tipoNeuronio
	 */
	void criarCamadaNeural( int quantidadeNeuronios, Class<? extends Neuronio> tipoNeuronio, FuncaoAtivacao funcaoAtivacao );
	
	/**
	 * Método que cria um neuronio a partir de uma tipo de neuronio (Classes que implementem a interface Neuronio).
	 * 
	 * @param tipoNeuronio
	 * @return
	 */
	Neuronio criarNeuronio(Class<? extends Neuronio> tipoNeuronio);
	
	/**
	 * Ajusta os pesos das sinapses dos neurônios, de forma a deixar o neurônio preparado
	 * para separar corretamente padrões linearmente separáveis.
	 * 
	 * @param padroesTreinamento
	 * @param saidasDesejadas
	 */
	void treinarRedePerceptron(List<Padrao> padroesTreinamento, double[][] saidasDesejadas);
	
	
	void autoOrganizar(List<Padrao> padroesEntrada);

}
